﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using RegionSplittor.Data;

namespace RegionSplittor.Utils
{
	public class BeamOperator
	{
		public static BeamOrderType GetBeamOrderType(FamilyInstance famIns)
		{
			BeamOrderType result = BeamOrderType.BT_SecondaryBeam;
			Document document = famIns.Document;
			IEnumerable<ElementId> joinedElements = JoinGeometryUtils.GetJoinedElements(document, famIns);
			ElementId levelId = famIns.GetParameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsElementId();
			int num = 0;
			foreach (ElementId elementId in joinedElements)
			{
				Element element = document.GetElement(elementId);
				if (element != null && (BeamOperator.IsColumnWithSameLevel(element, levelId) || BeamOperator.IsShearWallWithSameLevel(element, levelId)))
				{
					num++;
				}
				if (2 == num)
				{
					result = BeamOrderType.BT_PrimaryBeam;
					break;
				}
			}
			return result;
		}

		public static bool IsPrimaryBeam(FamilyInstance famIns)
		{
			bool result = false;
			if (famIns.Category.Id.IntegerValue != -2001320)
			{
				return result;
			}
			if (BeamOperator.GetBeamOrderType(famIns) == BeamOrderType.BT_PrimaryBeam)
			{
				result = true;
			}
			return result;
		}

		public static bool IsSecondaryBeam(FamilyInstance famIns)
		{
			bool result = false;
			BeamOrderType beamOrderType = BeamOperator.GetBeamOrderType(famIns);
			if (BeamOrderType.BT_SecondaryBeam == beamOrderType)
			{
				result = true;
			}
			return result;
		}

		public static bool IsColumn(Element ele)
		{
			bool result = false;
			if (ele is FamilyInstance)
			{
				FamilyInstance familyInstance = ele as FamilyInstance;
				if (familyInstance.Category.Id.IntegerValue == -2000100 || familyInstance.Category.Id.IntegerValue == -2001330)
				{
					result = true;
				}
			}
			return result;
		}

		public static bool IsBeamOrWall(Element ele)
		{
			bool result = false;
			if (ele is Wall || (ele is FamilyInstance && ele.Category.Id.IntegerValue == -2001320))
			{
				result = true;
			}
			return result;
		}

		public static double GetEleParamDoubleValue(Element ele, string strParamName)
		{
			return ele.GetParameter(strParamName).AsDouble();
		}

		public static double GetBeamHeight(FamilyInstance famIns)
		{
			return BeamOperator.GetEleParamDoubleValue(famIns.Document.GetElement(famIns.GetTypeId()), "h");
		}

		public static Curve GetBeamLocCurve(ElementId beamId, Autodesk.Revit.DB.Document doc)
		{
			Curve result = null;
			FamilyInstance familyInstance = doc.GetElement(beamId) as FamilyInstance;
			if (familyInstance != null)
			{
				LocationCurve locationCurve = familyInstance.Location as LocationCurve;
				if (locationCurve != null)
				{
					result = locationCurve.Curve.Clone();
				}
			}
			return result;
		}

		private static bool IsColumnWithSameLevel(Element ele, ElementId levelId)
		{
			bool result = false;
			if ((ele.Category.Id.IntegerValue == -2000100 || ele.Category.Id.IntegerValue == -2001330) && (ele as FamilyInstance).GetParameter(BuiltInParameter.SCHEDULE_TOP_LEVEL_PARAM).AsElementId().IntegerValue == levelId.IntegerValue)
			{
				result = true;
			}
			return result;
		}

		private static bool IsShearWallWithSameLevel(Element ele, ElementId levelId)
		{
			bool result = false;
			if (ele is Wall)
			{
				Wall elem = ele as Wall;
				int num = elem.GetParameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).AsInteger();
				ElementId elementId = elem.GetParameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
				if (1 == num && elementId.IntegerValue == levelId.IntegerValue)
				{
					result = true;
				}
			}
			return result;
		}

		private static Face GetTopFace(FamilyInstance famIns)
		{
			Face result = null;
			List<Face> elementAllFace = ElementGeometryManager.GetElementAllFace(famIns);
			if (0 < elementAllFace.Count)
			{
				foreach (Face face in elementAllFace)
				{
					if (!(null == face) && face.ComputeNormal(UV.Zero).Z > 0.0)
					{
						result = face;
						break;
					}
				}
			}
			return result;
		}

		private static ElementArray GetBeamJoinElementByIndex(int nIndex, FamilyInstance beam)
		{
			ElementArray result = new ElementArray();
			Dictionary<int, ElementArray> beamJoinElementDic = BeamOperator.GetBeamJoinElementDic(beam);
			if (beamJoinElementDic.Count > 0)
			{
				result = beamJoinElementDic[nIndex];
			}
			return result;
		}

		private static Dictionary<int, ElementArray> GetBeamJoinElementDic(FamilyInstance beam)
		{
			Dictionary<int, ElementArray> dictionary = new Dictionary<int, ElementArray>();
			LocationCurve locationCurve = beam.Location as LocationCurve;
			if (locationCurve != null)
			{
				int num = 0;
				ElementArray value = locationCurve.get_ElementsAtJoin(num);
				dictionary.Add(num, value);
				num = 1;
				ElementArray value2 = locationCurve.get_ElementsAtJoin(num);
				dictionary.Add(num, value2);
			}
			return dictionary;
		}

		private static bool IsBeamJoinColumnOrWall(int nIndex, FamilyInstance beam, ElementId levelId)
		{
			bool result = false;
			foreach (object obj in BeamOperator.GetBeamJoinElementByIndex(nIndex, beam))
			{
				Element element = (Element)obj;
				if (element != null && (BeamOperator.IsColumnWithSameLevel(element, levelId) || BeamOperator.IsShearWallWithSameLevel(element, levelId)))
				{
					result = true;
				}
			}
			return result;
		}
	}
}
